package com.joker;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import java.util.concurrent.TimeUnit;

import static com.joker.ZookeeperConstant.ZK_ADDRESS;

public class DistributedLockWithCurator {
    private CuratorFramework client;
    private InterProcessMutex lock;

    private static final String LOCK_PATH = "/distributed-lock";

    public DistributedLockWithCurator() {
        // 创建Curator客户端
        this.client = CuratorFrameworkFactory.newClient(
                ZK_ADDRESS,
                new ExponentialBackoffRetry(1000, 3)
        );
        this.client.start();
        
        // 创建分布式锁
        this.lock = new InterProcessMutex(client, LOCK_PATH);
    }

    // 获取锁（阻塞直到获取成功）
    public boolean acquireLock() {
        try {
            lock.acquire();
            System.out.println(Thread.currentThread().getName() + " 获取锁成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 尝试获取锁（带超时时间）
    public boolean tryAcquireLock(long time, TimeUnit unit) {
        try {
            boolean acquired = lock.acquire(time, unit);
            if (acquired) {
                System.out.println(Thread.currentThread().getName() + " 获取锁成功");
            } else {
                System.out.println(Thread.currentThread().getName() + " 获取锁超时");
            }
            return acquired;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    // 释放锁
    public void releaseLock() {
        try {
            if (lock.isAcquiredInThisProcess()) {
                lock.release();
                System.out.println(Thread.currentThread().getName() + " 释放锁成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close() {
        if (client != null) {
            client.close();
        }
    }
}